using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using AlgorithmsVisualized.Components;
//using AlgorithmsVisualized.Controls;
using GraphConstructor;

namespace AlgorithmsVisualized
{
    public partial class frmMain : Form
    {
        AssemblyLoader _loader = new AssemblyLoader();
        IGraph _selectedAlgo = null;
        IEnumerator<IStep> _enumerable;

        public frmMain()
        {
            InitializeComponent();
        }
        private void frmMain_Load(object sender, EventArgs e)
        {
            _loader.LoadAssemblies("Algorithms");
            cmbAvailableAlgo.DataSource = _loader.ClassNames;
        }
        private void frmMain_MouseDown(object sender, MouseEventArgs e)
        {
        }

        private void graphPic_NewEdgeRequest(object sender, ref GraphConstructor.EdgeArgs args)
        {
            GraphConstructor.Util.MakeEdge(ref args);
            return;
            frmNewEdge newEdge = new frmNewEdge();
            DialogResult dlgRes = newEdge.ShowDialog();
            if (dlgRes == DialogResult.OK)
            {
                args.Weight = newEdge.Weight;
                args.IsDirected = true;
            }
        }
        private void graphPic_SelectionChanged(object sender, GraphConstructor.ShapeArgs args)
        {
            propGrd.SelectedObject = args.Shape;
        }

        private void cmbAvailableAlgo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbAvailableAlgo.Text != "")
            {
                _selectedAlgo = _loader.Objects[_loader.ClassNames.IndexOf(cmbAvailableAlgo.Text)];
                richTextBox1.Text = "Description:" + _selectedAlgo.Description + "\r\n";
                richTextBox1.Text += "Complexty:" + _selectedAlgo.Complexty + "\r\n";
            }
        }
        private void nextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_enumerable.MoveNext() == false)
            {
                Draw(_enumerable.Current);
                nextToolStripMenuItem.Enabled = false;
                DialogResult dlg = MessageBox.Show("No more steps !, start over?", _selectedAlgo.Name + " done", MessageBoxButtons.YesNo);
                if (dlg == DialogResult.Yes)
                    _enumerable.Reset();
                Draw(_enumerable.Current);
            }
            else
                Draw(_enumerable.Current);
        }
        private void initializeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Draw(null);
            _selectedAlgo.Nodes = new List<Node>(graphPic.Nodes);
            _selectedAlgo.Edges = new List<Edge>(graphPic.Edges);
            _selectedAlgo.StartNodes = new List<Node>();
            _selectedAlgo.StartNodes.AddRange(graphPic.StartNodes);
            _enumerable = _selectedAlgo.GetEnumerator();

            _enumerable.Reset();
            nextToolStripMenuItem.Enabled = true;
        }
        private void runToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _selectedAlgo.Nodes = new List<Node>(graphPic.Nodes);
            _selectedAlgo.Edges = new List<Edge>(graphPic.Edges);
            _selectedAlgo.StartNodes.Clear();
            _selectedAlgo.StartNodes.AddRange(graphPic.StartNodes);
            _enumerable = _selectedAlgo.GetEnumerator();

            _enumerable.Reset();
            while (_enumerable.MoveNext()) ;
            Draw(_enumerable.Current);
            _enumerable.Reset();
        }

        private void Draw(IStep iStep)
        {
            // Reset all nodes and edges
            foreach (Node n in graphPic.Nodes)
            {
                n.IsBold = false;
                n.Deselect();
            }
            foreach (Node n in graphPic.StartNodes)
                n.IsBold = true;
            foreach (Edge edge in graphPic.Edges)
                edge.Deselect();

            // Mark new nodes and edges
            if (iStep != null)
            {
                IGraph g = iStep.State;
                foreach (Node n in g.Nodes)
                {
                    n.IsBold = true;
                    n.Select();
                }
                foreach (Edge edge in g.Edges)
                    edge.Select();
            }
            graphPic.Invalidate();

            if (iStep != null && iStep.IsFinal)
                MessageBox.Show("Done");
            /*
            foreach (Node n in g.Nodes)
            {
                if (n.Parent == null)
                    continue;
                int ind = g.Edges.IndexOf(new Edge(n.Parent.ID + n.ID, 0));
                if (ind != -1)
                    g.Edges[ind].Select();
            }*/
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dlgRes = saveFileDialog1.ShowDialog();
            if (dlgRes == DialogResult.OK)
            {
                FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.OpenOrCreate);
                graphPic.Save(fs);
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dlgRes = openFileDialog1.ShowDialog();
            if (dlgRes == DialogResult.OK)
            {
                FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.OpenOrCreate);
                graphPic.Load(fs);
            }
        }
    }
}
